package com.example.bicycle.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.util.SaResult;
import com.example.bicycle.domain.dto.SetAllBikesDto;
import com.example.bicycle.domain.dto.UserLocationDto;
import com.example.bicycle.domain.entity.ElectricBike;
import com.example.bicycle.domain.mqtt.PublishSettingMessageVo;
import com.example.bicycle.domain.mqtt.PublishSwitchMessageVo;
import com.example.bicycle.domain.vo.PageVo;
import com.example.bicycle.mqtt.MqttMessageService;
import com.example.bicycle.service.ElectricBikeService;
import com.example.bicycle.service.RideRecordService;
import com.example.bicycle.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static com.example.bicycle.domain.enums.AppHttpCodeEnum.BIKE_SWITCH_OFF;
import static com.example.bicycle.domain.enums.AppHttpCodeEnum.BIKE_SWITCH_ON;

@SaCheckLogin
@RestController
@RequestMapping("/bicycle/")
public class BikeController {
    private final ElectricBikeService electricBikeService;
    private final RideRecordService rideRecordService;
    private final MqttMessageService mqttMessageService;
    private final String topic = "$delayed/1/control-";
    private Integer lock = 1;
    private Integer unlock = 0;

    @Autowired
    public BikeController(ElectricBikeService electricBikeService, RideRecordService rideRecordService, MqttMessageService mqttMessageService) {
        this.electricBikeService = electricBikeService;
        this.rideRecordService = rideRecordService;
        this.mqttMessageService = mqttMessageService;
    }

    @GetMapping("getOne")
    public SaResult getOne(@RequestParam("bikeId") Integer bikeId) {
        ElectricBike byId = electricBikeService.getById(bikeId);
        return SaResult.data(byId);
    }

    @PostMapping("addOne")
    public SaResult addOne(@RequestBody ElectricBike bike) {
        /* 默认开关和使用为关闭 */
        bike.setSwitchState(BIKE_SWITCH_OFF.getCode());
        bike.setIsUsing(BIKE_SWITCH_OFF.getCode());
        electricBikeService.save(bike);
        return SaResult.ok("添加成功");
    }

    @PutMapping("putOne")
    public SaResult putOne(@RequestBody ElectricBike bike){
        electricBikeService.updateById(bike);
        return SaResult.ok("修改成功");
    }

    @DeleteMapping("deleteOne")
    public SaResult deleteOne(@RequestParam Integer bikeId){
        electricBikeService.removeById(bikeId);
        return SaResult.ok("删除成功");
    }

    @PostMapping("setAllBikes")
    public SaResult setAllBikes(@RequestBody SetAllBikesDto setAllBikesDto) {
        ElectricBike temp = BeanCopyUtils.copyBean(setAllBikesDto,ElectricBike.class);
        List<ElectricBike> list = electricBikeService.list();
        electricBikeService.updateBatchById(list);
        for (ElectricBike electricBike : list) {
            electricBike.copyAttributesFrom(temp);
            PublishSettingMessageVo setting = electricBikeService.setting(electricBike.getBikeId(), electricBike.getLightThreshold(), setAllBikesDto.getIsSyncTime());
            mqttMessageService.publish(topic+electricBike.getBikeId().toString(),setting);
        }
        return SaResult.ok("所有单车设置成功");
    }
    /**
     * 根据用户确认单车列表
     *
     * @param pageNum         页面num
     * @param pageSize        页面大小
     * @param userLocationDto 用户位置dto
     * @return {@link SaResult}
     */
    @PostMapping("list")
    public SaResult list(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize, @RequestBody UserLocationDto userLocationDto) {
        PageVo pageVo = electricBikeService.listByUserLocation(pageNum, pageSize, userLocationDto);
        return SaResult.data(pageVo);
    }

    /**
     * 根据用户确认单车列表
     *
     * @param pageNum         页面num
     * @param pageSize        页面大小
     * @param userLocationDto 用户位置dto
     * @return {@link SaResult}
     */
    @PostMapping("availableList")
    public SaResult availableList(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize, @RequestBody UserLocationDto userLocationDto) {
        PageVo pageVo = electricBikeService.availableBikeByUserLocation(pageNum, pageSize, userLocationDto);
        return SaResult.data(pageVo);
    }

    @PostMapping("lock")
    public SaResult lock(@RequestParam("bikeId") Integer bikeId, @RequestBody UserLocationDto userLocationDto) {
        /* 封装好发送类 */
        PublishSwitchMessageVo publishMessageVo = new PublishSwitchMessageVo();
        publishMessageVo.setLock(lock);
        /* 在这插入发布信息的内容 */
        mqttMessageService.publish(topic+bikeId.toString(),publishMessageVo);
        if(electricBikeService.lock(bikeId,userLocationDto)){
            return SaResult.ok("锁定成功");
        }
        return SaResult.error("锁定失败");
    }

    @PostMapping("unlock")
    public SaResult unlock(@RequestParam("bikeId") Integer bikeId, @RequestBody UserLocationDto userLocationDto) {
        /* 封装好发送类 */
        PublishSwitchMessageVo publishMessageVo = new PublishSwitchMessageVo();
        publishMessageVo.setLock(unlock);
        /* 在这插入发布信息的内容 */
        mqttMessageService.publish(topic+bikeId.toString(),publishMessageVo);
        if(electricBikeService.unlock(bikeId,userLocationDto)){
            return SaResult.ok("解锁成功");
        }
        return SaResult.error("解锁失败");
    }

    /**
     * 租借单车
     *
     * @param bikeId          自行车id
     * @param userLocationDto 用户位置dto
     * @return {@link SaResult}
     */
    @PostMapping("rent")
    public SaResult rent(@RequestParam("bikeId") Integer bikeId, @RequestBody UserLocationDto userLocationDto) {
        /* 封装好发送类 */
        PublishSwitchMessageVo publishMessageVo = new PublishSwitchMessageVo();
        publishMessageVo.setLock(unlock);
        /* 在这插入发布信息的内容 */
        mqttMessageService.publish(topic+bikeId.toString(),publishMessageVo);
        if(electricBikeService.rent(bikeId,userLocationDto)){
            return SaResult.ok("租借成功");
        }
        return SaResult.error("租借失败");
    }

    /**
     * 返还自行车
     *
     * @param bikeId          自行车id
     * @param userLocationDto 用户位置dto
     * @return {@link SaResult}
     */
    @PostMapping("return")
    public SaResult returnBike(@RequestParam("bikeId") Integer bikeId, @RequestBody UserLocationDto userLocationDto) {
        /* 封装好发送类 */
        PublishSwitchMessageVo publishMessageVo = new PublishSwitchMessageVo();
        publishMessageVo.setLock(lock);
        /* 在这插入发布信息的内容 */
        mqttMessageService.publish(topic+bikeId.toString(),publishMessageVo);
        if(electricBikeService.returnBike(bikeId,userLocationDto)){
            return SaResult.ok("归还成功");
        }
        return SaResult.error("归还失败");
    }

}
